package com.arpa.wms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.jpush.api.utils.StringUtils;
import com.arpa.core.web.Result;
import com.arpa.ntocc.common.common.cache.AreaCache;
import com.arpa.ntocc.common.common.cache.PartyCache;
import com.arpa.ntocc.common.common.exception.ServiceException;
import com.arpa.ntocc.common.common.util.CommonUtil;
import com.arpa.ntocc.common.common.util.UserUtil;
import com.arpa.wms.cache.CarrierCache;
import com.arpa.wms.cache.WarehouseCache;
import com.arpa.wms.domain.consts.CommonConst;
import com.arpa.wms.domain.consts.NumConst;
import com.arpa.wms.domain.dto.CarrierDTO;
import com.arpa.wms.domain.dto.CarrierauditDTO;
import com.arpa.wms.domain.entity.Carrier;
import com.arpa.wms.domain.entity.Container;
import com.arpa.wms.domain.enums.CarrierTypeEnum;
import com.arpa.wms.domain.enums.StatusEnum;
import com.arpa.wms.domain.vo.CarrierVO;
import com.arpa.wms.mapper.CarrierMapper;
import com.arpa.wms.service.ICarrierService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 承运商 服务实现类
 * </p>
 *
 * @author LEO
 * @since 2021-2-22
 */
@Service()
public class CarrierServiceImpl extends ServiceImpl<CarrierMapper, Carrier> implements ICarrierService {
    private static final String CARRIER_NAME_MANAGE = "承运商名称不能重复";
    private static final String CARRIER_CODE_MANAGE = "承运商编码不能重复";
    private final AreaCache areaCache;

    private final CarrierCache carrierCache;

    private final PartyCache partyCache;

    private final WarehouseCache warehouseCache;

    public CarrierServiceImpl(AreaCache areaCache, CarrierCache carrierCache ,PartyCache partyCache, WarehouseCache warehouseCache) {
        this.areaCache = areaCache;
        this.carrierCache = carrierCache;
        this.partyCache = partyCache;
        this.warehouseCache = warehouseCache;
    }


    /**
     * 查询列表
     *
     * @param CarrierDto
     * @return
     */
    @Override
    public List<CarrierVO> queryList(CarrierDTO CarrierDto) {
        //排序字段名需要驼峰转数据库下划线类型字段名
        if (StringUtils.isNotEmpty(CarrierDto.getSortField())) {
            CarrierDto.setSortField(CommonUtil.camel2Underline(CarrierDto.getSortField()));
        }
        List<CarrierVO> carrierVos = baseMapper.queryList(CarrierDto);
        for (CarrierVO carrierVO : carrierVos) {
            carrierVO.setCarrierTypeName(CarrierTypeEnum.translate(carrierVO.getCarrierType()));
        }
        return carrierVos;
    }

    /**
     * 查询合计,包含总数
     *
     * @param CarrierDto
     * @return
     */
    @Override
    public CarrierVO queryListSum(CarrierDTO CarrierDto) {
        return baseMapper.queryListSum(CarrierDto);
    }

    /**
     * 新增
     *
     * @param carrier
     * @return
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public int insert(Carrier carrier) {
        carrier.setStatus(StatusEnum.ACTIVE.getValue());
        carrier.setCode(IdUtil.simpleUUID());
        List<String> areaList = carrier.getAreaList();
        // 前端 参数 下标 限制 为 3, 所以 这里 由 4 改为 3
        if (IterUtil.isNotEmpty(areaList) && areaList.size() == 3) {
            // 设置 发件人省市区
            carrier.setSenderProvince(areaList.get(0));
            carrier.setSenderCity(areaList.get(1));
            carrier.setSenderDistrict(areaList.get(2));
        }
        int code = baseMapper.selectCount(new QueryWrapper<Carrier>().lambda().eq(Carrier::getCarrierCode, carrier.getCarrierCode()).eq(Carrier::getGroupCode,UserUtil.getBranchCode()));
        if (code > NumConst.NUM_ZERO) {
            throw new ServiceException(CARRIER_CODE_MANAGE);
        }
        int name = baseMapper.selectCount(new QueryWrapper<Carrier>().lambda().eq(Carrier::getName, carrier.getName()).eq(Carrier::getGroupCode,UserUtil.getBranchCode()));
        if (name > NumConst.NUM_ZERO) {
            throw new ServiceException(CARRIER_NAME_MANAGE);
        }
        String createdBy = UserUtil.getCode();
        String createdName = partyCache.translate(createdBy);
        // 设置 发件人详细地址
        if (!carrier.getAddress().isEmpty()){
            carrier.setSendAddress(carrier.getAddress());
        }
//        String warehouseCode = UserUtil.getLoginWarehouseCodeOrShipmentCode();
//        carrier.setWarehouseCode(warehouseCode);
//        carrier.setWarehouseName(warehouseCache.translate(warehouseCode));
        //所属机构
        carrier.setGroupCode(UserUtil.getBranchCode());
        //当前操作人
        carrier.setCreatedBy(createdBy);
        carrier.setCreatedName(createdName);
        carrier.setModifiedBy(createdBy);
        carrier.setModifiedName(createdName);
        carrierCache.flushCache(carrier);
        return baseMapper.insert(carrier);
    }

    /**
     * 更新
     *
     * @param carrier
     * @return
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public int update(Carrier carrier) {
        //承运商状态为审核未通过时，更新状态为待审核
        if (CommonConst.STR_TWO.equals(carrier.getStatus())) {
            carrier.setStatus(CommonConst.STR_ZERO);
        }
        Map<String, Object> params = new HashMap<>();
        params.put("code", carrier.getCode());
        List<String> areaList = carrier.getAreaList();
        if (IterUtil.isNotEmpty(areaList) && areaList.size() == 4) {
            carrier.setCountry(areaList.get(0));
            carrier.setProvince(areaList.get(1));
            carrier.setCity(areaList.get(2));
            carrier.setCounty(areaList.get(3));
        }
        carrier.setModifiedBy(UserUtil.getCode());
        carrier.setModifiedName(partyCache.translate(UserUtil.getCode()));
        carrier.setGmtModified(LocalDateTime.now());
        carrierCache.flushCache(carrier);
        return baseMapper.update(carrier, new QueryWrapper<Carrier>().allEq(params));
    }


    /**
     * 通过code查询承运商信息
     * 使用缓存查询
     *
     * @param code
     * @return
     */
    @Override
    public CarrierVO getOneInfo(String code) {
        Carrier entity = baseMapper.selectOne(new QueryWrapper<Carrier>().lambda().eq(Carrier::getCode, code).eq(Carrier::getGroupCode,UserUtil.getBranchCode()));
        Optional.ofNullable(entity).orElseThrow(() -> new ServiceException("没有查询到信息"));
        CarrierVO CarrierVo = new CarrierVO();
        BeanUtil.copyProperties(entity, CarrierVo);
        List<String> areaList = new ArrayList<>();
        areaList.add(entity.getCountry());
        areaList.add(entity.getProvince());
        areaList.add(entity.getCity());
        areaList.add(entity.getCounty());
        String areaStr = "";
        if (StrUtil.isNotBlank(entity.getCountry())) {
            areaStr = areaCache.translateCountry(entity.getCountry());
        }

        if (StrUtil.isNotBlank(entity.getProvince())) {
            if (StrUtil.isNotBlank(areaStr)) {
                areaStr = areaStr + "/" + entity.getProvince();
            } else {
                areaStr = entity.getProvince();
            }
        }
        if (StrUtil.isNotBlank(entity.getCity())) {
            if (StrUtil.isNotBlank(areaStr)) {
                areaStr = areaStr + "/" + entity.getCity();
            } else {
                areaStr = entity.getCity();
            }
        }
        if (StrUtil.isNotBlank(entity.getCounty())) {
            if (StrUtil.isNotBlank(areaStr)) {
                areaStr = areaStr + "/" + entity.getCounty();
            } else {
                areaStr = entity.getCounty();
            }
        }
        CarrierVo.setArea(areaStr);


        CarrierVo.setAreaList(areaList);
        return CarrierVo;
    }

    /**
     * 承运商审核
     *
     * @param carrierauditDTO
     * @return
     */
    @Override
    public int audit(CarrierauditDTO carrierauditDTO) {
        Carrier carrier = new Carrier().setStatus(carrierauditDTO.getStatus()).setApprovedBy(carrierauditDTO.getApprovedBy()).setApprovedName(carrierauditDTO.getApprovedName());

        int bool = baseMapper.update(carrier, new LambdaUpdateWrapper<Carrier>().eq(Carrier::getCode, carrierauditDTO.getCode()).eq(Carrier::getGroupCode,UserUtil.getBranchCode()));
        if (bool != 0) {
            carrierCache.flushCache(carrier);
        }
        return bool;
    }
    /**
     * 承运商校验
     *
     * @param entity
     * @return
     */
    @Override
    public void validCarrier(Carrier entity,boolean update) {
        String carrierName = entity.getName();
        String shipmentCode = entity.getShipmentCode();
        if (StrUtil.equalsAny(entity.getOuterCode(),CommonConst.SF)) {
           if (StrUtil.isEmpty(entity.getCustomerCode()) && StrUtil.equalsAny(entity.getPlatformType(),CommonConst.TB,CommonConst.TM,CommonConst.JD)) {
               throw new ServiceException("淘宝/天猫、京东平台顺丰月结卡号为必填项，不能为空");
           }
           if (CommonConst.JD.equals(entity.getPlatformType())) {
               if (StrUtil.isEmpty(entity.getExpressType())) {
                   throw new ServiceException("京东顺丰快件产品类别为必填项，不能为空");
               }
               if (StrUtil.isEmpty(entity.getExpressPayMethod())) {
                   throw new ServiceException("京东顺丰快递费付款方式为必填项，不能为空");
               }
           }
        }
        //更新操作，值校验顺丰快递必填项
        if (update) {
            return;
        }
        Carrier carrier = this.getOne(new QueryWrapper<Carrier>().lambda().eq(Carrier::getName, carrierName).eq(Carrier::getGroupCode,UserUtil.getBranchCode())
                .eq(Carrier::getShipmentCode,shipmentCode));
        if (null != carrier) {
            throw new ServiceException("承运商名称" + carrierName + "已存在，请确认");
        }
    }

    /**
     * 删除
     * @param codes
     * @return
     */
    @Override
    public Result remove(String codes){
        List<Carrier> carriers = this.list(new LambdaQueryWrapper<Carrier>().in(Carrier::getCode, codes));
        carriers.stream().forEach(e -> {
            carrierCache.flushCache(e);
        });
        this.remove(new QueryWrapper<Carrier>().lambda().in(Carrier::getCode, codes).eq(Carrier::getGroupCode,UserUtil.getBranchCode()));
        return Result.ok();
    }


}
